home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2007 January, February, March & April
/
Chip-Cover-CD-2007-02.iso
/
Pakiet bezpieczenstwa
/
mini Pentoo LiveCD 2006.1
/
mpentoo-2006.1.iso
/
livecd.squashfs
/
usr
/
lib
/
python2.4
/
site-packages
/
impacket
/
ntlm.py
< prev
next >
Wrap
Text File
|
2006-05-23
|
9KB
|
260 lines
# Copyright (c) 2003-2006 CORE Security Technologies
#
# This software is provided under under a slightly modified version
# of the Apache Software License. See the accompanying LICENSE file
# for more information.
#
# $Id: ntlm.py,v 1.2 2006/05/23 21:19:25 gera Exp $
#
from impacket.structure import Structure
try:
from Crypto.Cipher import DES
from Crypto.Hash import MD4
POW = None
except Exception:
try:
import POW
except Exception:
pass
NTLM_AUTH_NONE = 1
NTLM_AUTH_CONNECT = 2
NTLM_AUTH_CALL = 3
NTLM_AUTH_PKT = 4
NTLM_AUTH_PKT_INTEGRITY = 5
NTLM_AUTH_PKT_PRIVACY = 6
NTLMSSP_KEY_56 = 0x80000000
NTLMSSP_KEY_EXCHANGE = 0x40000000
NTLMSSP_KEY_128 = 0x20000000
# NTLMSSP_ = 0x10000000
# NTLMSSP_ = 0x08000000
# NTLMSSP_ = 0x04000000
# NTLMSSP_ = 0x02000000
# NTLMSSP_ = 0x01000000
NTLMSSP_TARGET_INFO = 0x00800000
# NTLMSSP_ = 0x00400000
# NTLMSSP_ = 0x00200000
# NTLMSSP_ = 0x00100000
NTLMSSP_NTLM2_KEY = 0x00080000
NTLMSSP_CHALL_NOT_NT = 0x00040000
NTLMSSP_CHALL_ACCEPT = 0x00020000
NTLMSSP_CHALL_INIT = 0x00010000
NTLMSSP_ALWAYS_SIGN = 0x00008000 # forces the other end to sign packets
NTLMSSP_LOCAL_CALL = 0x00004000
NTLMSSP_WORKSTATION = 0x00002000
NTLMSSP_DOMAIN = 0x00001000
# NTLMSSP_ = 0x00000800
# NTLMSSP_ = 0x00000400
NTLMSSP_NTLM_KEY = 0x00000200
NTLMSSP_NETWARE = 0x00000100
NTLMSSP_LM_KEY = 0x00000080
NTLMSSP_DATAGRAM = 0x00000040
NTLMSSP_SEAL = 0x00000020
NTLMSSP_SIGN = 0x00000010 # means packet is signed, if verifier is wrong it fails
# NTLMSSP_ = 0x00000008
NTLMSSP_TARGET = 0x00000004
NTLMSSP_OEM = 0x00000002
NTLMSSP_UNICODE = 0x00000001
class NTLMAuthHeader(Structure):
commonHdr = (
('auth_type', 'B=10'),
('auth_level','B'),
('auth_pad_len','B=0'),
('auth_rsvrd','"\x00'),
('auth_ctx_id','<L=747920'),
)
structure = (
('data',':'),
)
class NTLMAuthNegotiate(NTLMAuthHeader):
structure = (
('','"NTLMSSP\x00'),
('message_type','<L=1'),
('flags','<L'),
('domain_len','<H-domain_name'),
('domain_max_len','<H-domain_name'),
('domain_offset','<L'),
('host_len','<H-host_name'),
('host_maxlen','<H-host_name'),
('host_offset','<L'),
('host_name',':'),
('domain_name',':'))
def __init__(self):
NTLMAuthHeader.__init__(self)
self['flags']= (
NTLMSSP_KEY_128 |
NTLMSSP_KEY_EXCHANGE|
# NTLMSSP_LM_KEY |
NTLMSSP_NTLM_KEY |
NTLMSSP_UNICODE |
# NTLMSSP_ALWAYS_SIGN |
NTLMSSP_SIGN |
NTLMSSP_SEAL |
# NTLMSSP_TARGET |
0)
self['host_name']=''
self['domain_name']=''
def __str__(self):
self['host_offset']=32
self['domain_offset']=32+len(self['host_name'])
return NTLMAuthHeader.__str__(self)
class NTLMAuthChallenge(NTLMAuthHeader):
structure = (
('','"NTLMSSP\x00'),
('message_type','<L=2'),
('domain_len','<H-domain_name'),
('domain_max_len','<H-domain_name'),
('domain_offset','<L'),
('flags','<L'),
('challenge','8s'),
('reserved','"\x00\x00\x00\x00\x00\x00\x00\x00'),
('domain_name',':'))
class NTLMAuthChallengeResponse(NTLMAuthHeader):
structure = (
('','"NTLMSSP\x00'),
('message_type','<L=3'),
('lanman_len','<H-lanman'),
('lanman_max_len','<H-lanman'),
('lanman_offset','<L'),
('ntlm_len','<H-ntlm'),
('ntlm_max_len','<H-ntlm'),
('ntlm_offset','<L'),
('domain_len','<H-domain_name'),
('domain_max_len','<H-domain_name'),
('domain_offset','<L'),
('user_len','<H-user_name'),
('user_max_len','<H-user_name'),
('user_offset','<L'),
('host_len','<H-host_name'),
('host_max_len','<H-host_name'),
('host_offset','<L'),
('session_key_len','<H-session_key'),
('session_key_max_len','<H-session_key'),
('session_key_offset','<L'),
('flags','<L'),
('domain_name',':'),
('user_name',':'),
('host_name',':'),
('lanman',':'),
('ntlm',':'),
('session_key',':'))
def __init__(self, username, password, challenge):
NTLMAuthHeader.__init__(self)
self['session_key']=''
self['user_name']=username.encode('utf-16le')
self['domain_name']='' #"CLON".encode('utf-16le')
self['host_name']='' #"BETS".encode('utf-16le')
self['flags'] = ( #authResp['flags']
# we think (beto & gera) that his flags force a memory conten leakage when a windows 2000 answers using uninitializaed verifiers
NTLMSSP_KEY_128 |
NTLMSSP_KEY_EXCHANGE|
# NTLMSSP_LM_KEY |
NTLMSSP_NTLM_KEY |
NTLMSSP_UNICODE |
# NTLMSSP_ALWAYS_SIGN |
NTLMSSP_SIGN |
NTLMSSP_SEAL |
# NTLMSSP_TARGET |
0)
# Here we do the stuff
if username and password:
lmhash = compute_lmhash(password)
nthash = compute_nthash(password)
self['lanman']=get_ntlmv1_response(lmhash, challenge)
self['ntlm']=get_ntlmv1_response(nthash, challenge) # This is not used for LM_KEY nor NTLM_KEY
else:
self['lanman'] = ''
self['ntlm'] = ''
if not self['host_name']:
self['host_name'] = 'NULL'.encode('utf-16le') # for NULL session there must be a hostname
def __str__(self):
self['domain_offset']=64
self['user_offset']=64+len(self['domain_name'])
self['host_offset']=self['user_offset']+len(self['user_name'])
self['lanman_offset']=self['host_offset']+len(self['host_name'])
self['ntlm_offset']=self['lanman_offset']+len(self['lanman'])
self['session_key_offset']=self['ntlm_offset']+len(self['ntlm'])
return NTLMAuthHeader.__str__(self)
class ImpacketStructure(Structure):
def set_parent(self, other):
self.parent = other
def get_packet(self):
return str(self)
def get_size(self):
return len(self)
class NTLMAuthVerifier(NTLMAuthHeader):
structure = (
('version','<L=1'),
('data','12s'),
# ('_zero','<L=0'),
# ('crc','<L=0'),
# ('sequence','<L=0'),
)
KNOWN_DES_INPUT = "KGS!@#$%"
def __expand_DES_key( key):
# Expand the key from a 7-byte password key into a 8-byte DES key
key = key[:7]
key += '\x00'*(7-len(key))
s = chr(((ord(key[0]) >> 1) & 0x7f) << 1)
s = s + chr(((ord(key[0]) & 0x01) << 6 | ((ord(key[1]) >> 2) & 0x3f)) << 1)
s = s + chr(((ord(key[1]) & 0x03) << 5 | ((ord(key[2]) >> 3) & 0x1f)) << 1)
s = s + chr(((ord(key[2]) & 0x07) << 4 | ((ord(key[3]) >> 4) & 0x0f)) << 1)
s = s + chr(((ord(key[3]) & 0x0f) << 3 | ((ord(key[4]) >> 5) & 0x07)) << 1)
s = s + chr(((ord(key[4]) & 0x1f) << 2 | ((ord(key[5]) >> 6) & 0x03)) << 1)
s = s + chr(((ord(key[5]) & 0x3f) << 1 | ((ord(key[6]) >> 7) & 0x01)) << 1)
s = s + chr((ord(key[6]) & 0x7f) << 1)
return s
def __DES_block(key, msg):
if POW:
cipher = POW.Symmetric(POW.DES_ECB)
cipher.encryptInit(__expand_DES_key(key))
return cipher.update(msg)
else:
cipher = DES.new(__expand_DES_key(key),DES.MODE_ECB)
return cipher.encrypt(msg)
def ntlmssp_DES_encrypt(key, challenge):
answer = __DES_block(key[:7], challenge)
answer += __DES_block(key[7:14], challenge)
answer += __DES_block(key[14:], challenge)
return answer
def compute_lmhash(password):
# This is done according to Samba's encryption specification (docs/html/ENCRYPTION.html)
password = password.upper()
lmhash = __DES_block(password[:7], KNOWN_DES_INPUT)
lmhash += __DES_block(password[7:14], KNOWN_DES_INPUT)
return lmhash
def compute_nthash(password):
# This is done according to Samba's encryption specification (docs/html/ENCRYPTION.html)
password = unicode(password).encode('utf_16le')
if POW:
hash = POW.Digest(POW.MD4_DIGEST)
else:
hash = MD4.new()
hash.update(password)
return hash.digest()
def get_ntlmv1_response(key, challenge):
return ntlmssp_DES_encrypt(key, challenge)